/*
 * storage.h
 *
 *  Created on: Oct 17, 2013
 *      Author: Ken Arok
 */

#ifndef STORAGE_H_
#define STORAGE_H_

#include "compiler.h"

/* Logical Unit Number. */
#define LUN_0		ENABLE	//! Mass storage SD/MMC
#define LUN_1		DISABLE //! Spare
#define LUN_2		DISABLE //! Spare
#define LUN_3		DISABLE //! Spare
#define LUN_4		DISABLE //! Spare
#define LUN_5		DISABLE //! Spare
#define LUN_6		DISABLE //! Spare
#define LUN_7		DISABLE //! Spare
#define LUN_USB		DISABLE //! Mass storage USB


/* LUN 0 Definition. */
#define SD_MMC_SPI_MEM				LUN_0
#define LUN_ID_SD_MMC_SPI_MEM		LUN_ID_0
#define LUN_0_INCLUDE				"sdmmc_stack.h"
#define LUN_0_TestUnitReady			vSDMMC_TestUnitReady
#define LUN_0_ReadCapacity			vSDMMC_ReadCapacity
#define LUN_0_IsWriteProtected		vSDMMC_IsWriteProtected
#define LUN_0_IsRemoval				vSDMMC_IsRemoval
#define LUN_0_USBRead				vSDMMC_USBRead
#define LUN_0_USBWrite				vSDMMC_USBWrite
#define LUN_0_MemoryToRAM			vSDMMC_MemoryToRAM
#define LUN_0_RAMToMemory			vSDMMC_RAMToMemory
#define LUN_0_NAME					"\"SD/MMC Card\""


/* LUN USB Definition. */
#define USB_MEM									LUN_USB
#define LUN_ID_USB_MEM							LUN_ID_USB
#define LUN_USB_INCLUDE							"host_storage_stack.h"
#define LUN_USB_TestUnitReady(lun)				vHostStorage_TestUnitReady(lun)
#define LUN_USB_ReadCapacity(lun, nb_sector)	vHostStorage_ReadCapacity(lun, nb_sector)
#define LUN_USB_ReadSectorSize(lun)				vHostStorage_ReadSectorSize(lun)
#define LUN_USB_IsWriteProtected(lun)			vHostStorage_IsWriteProtected(lun)
#define LUN_USB_IsRemoval()						vHostStorage_IsRemoval()
#define LUN_USB_MemoryToRAM(addr, ram)			vHostStorage_ReadMemoryToRAM(addr, ram)
#define LUN_USB_RAMToMemory(addr, ram)			vHostStorage_WriteRAMToMemory(addr, ram)
#define LUN_USB_NAME							"\"Host Mass-Storage\""


/* Activation of Interface feature. */
#define ACCESS_USB			false	//! MEMORY <-> USB Interface
#define ACCESS_MEM_TO_RAM	true	//! MEMORY <-> RAM Interface

/* Action associated with memory access. */
#define vStorage_MemoryStartReadAction(nb_sector)
#define vStorage_MemoryStopReadAction()
#define vStorage_MemoryStartWriteAction(nb_sector)
#define vStorage_MemoryStopWriteAction()

typedef enum {
	STORAGE_GOOD = 0,	//! Success, memory storage ready.
	STORAGE_FAIL,		//! An error occurred.
	STORAGE_NO_PRESENT,	//! Memory storage unplugged.
	STORAGE_BUSY		//! Memory storage busy.
}storage_status_t;


/* Do not edit below. */
//! @{
#define LUN_ID_0		(0)
#define LUN_ID_1		(LUN_ID_0 + LUN_0)
#define LUN_ID_2		(LUN_ID_1 + LUN_1)
#define LUN_ID_3		(LUN_ID_2 + LUN_2)
#define LUN_ID_4		(LUN_ID_3 + LUN_3)
#define LUN_ID_5		(LUN_ID_4 + LUN_4)
#define LUN_ID_6		(LUN_ID_5 + LUN_5)
#define LUN_ID_7		(LUN_ID_6 + LUN_6)
#define MAX_LUN			(LUN_ID_7 + LUN_7)
#define LUN_ID_USB		(MAX_LUN)

//! @}


/** \brief Test storage unit weather readey or not.
 *
 * \param lun	Logical Unit Number.
 *
 * \return Status.
 */
extern storage_status_t vStorage_TestUnitReady(uint8_t lun);

/** \brief Read storage unit capacity.
 *
 * \param lun		Logical Unit Number.
 * \param nb_sector	Pointer to store number of sector.
 *
 * \return Status.
 */
extern storage_status_t vStorage_ReadCapacity(uint8_t lun, uint32_t *nb_sector);

/** \brief Read storage sector size.
 *
 * \param lun		Logical Unit Number.
 *
 * \return Size of sector.
 */
extern uint8_t vStorage_SectorSize(uint8_t lun);

/** \brief Check if unit is write protected.
 *
 * \param lun		Logical Unit Number.
 *
 * \return true if unit is write protected. Unless false.
 */
extern bool vStorage_IsWriteProtected(uint8_t lun);

/** \brief Check if unit is removal.
 *
 * \param lun		Logical Unit Number.
 *
 * \return true if unit is removal. Unless false.
 */
extern bool vStorage_IsRemoval(uint8_t lun);

/** \brief Get Unit Name.
 *
 * \param lun		Logical Unit Number.
 *
 * \return Pointer of Name string.
 */
extern const char *vStorage_Name(uint8_t lun);


#if ACCESS_USB == true

/** \brief Memory to USB interface.
 *
 * \param lun		Logical Unit Number.
 * \param addr		Address of memory.
 * \param nb_sector Number of sector.
 *
 * \return Status.
 */
extern storage_status_t vStorage_MemoryToUSB(uint8_t lun, uint32_t addr, uint16_t nb_sector);

/** \brief USB to Memory interface.
 *
 * \param lun		Logical Unit Number.
 * \param addr		Address of memory.
 * \param nb_sector Number of sector.
 *
 * \return Status.
 */
extern storage_status_t vStorage_USBToMemory(uint8_t lun, uint32_t addr, uint16_t nb_sector);

#endif /* ACCESS_USB */


#if ACCESS_MEM_TO_RAM == true

/** \brief Memory to RAM interface.
 *
 * \param lun		Logical Unit Number.
 * \param addr		Address of memory.
 * \param ram 		Pointer to RAM.
 *
 * \return Status.
 */
extern storage_status_t vStorage_MemoryToRAM(uint8_t lun, uint32_t addr, void *ram);

/** \brief RAM To Memory interface.
 *
 * \param lun		Logical Unit Number.
 * \param addr		Address of memory.
 * \param ram 		Pointer to RAM.
 *
 * \return Status.
 */
extern storage_status_t vStorage_RAMToMemory(uint8_t lun, uint32_t addr, const void *ram);

#endif /* ACCESS_MEM_TO_RAM */

#endif /* STORAGE_H_ */
